import React from 'react';
import { Button, Tag, Balloon, Message } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import track from 'utils/track';
import { navigate } from 'utils/router';
import { ENUM } from 'utils/constants.js';
import docs from 'utils/docs';
import { getFeature } from 'utils/features';
import sha1 from 'sha1';
import exceed from 'utils/apimap';
import './index.scss';
import intl from '../../../../../../../../../locale';

const codeScanMap = {
  RUNNING: intl.get({
    id: 'code-assets.components.codeScanInfo.Running',
    defaultMessage: '运行中',
  }),
  PASS: intl.get({ id: 'code-assets.components.codeScanInfo.Pass', defaultMessage: '通过' }),
  FAIL: intl.get({ id: 'code-assets.components.codeScanInfo.Failed', defaultMessage: '不通过' }),
  WARN: intl.get({ id: 'code-assets.components.codeScanInfo.Alerts', defaultMessage: '有告警' }),
  NOT_RUN: intl.get({
    id: 'code-assets.components.codeScanInfo.NotRunning',
    defaultMessage: '未运行',
  }),
};

const codeScanIconMap = {
  RUNNING: 'loading-fill',
  PASS: 'success-fill',
  FAIL: 'delete-fill',
  WARN: 'warning-fill',
  NOT_RUN: 'delete-fill',
};

// 对应颜色;
const codeScanColorMap = {
  RUNNING: '#1B9AEE',
  PASS: '#1dc11d',
  FAIL: 'red',
  WARN: 'orange',
  NOT_RUN: 'red',
};

const prefix = 'codescan-info';
export default class CodeScanInfo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // 默认不展开
      isShowCodeScan: false,
    };

    this.intervalCnt = -1;
  }

  componentDidMount() {
    // 如果有RUNNING态的扫描，设置一个定时器
    const { mergeRequestBuilds } = this.props;
    let running = false;
    mergeRequestBuilds.forEach((item) => {
      if (item.state === 'RUNNING') {
        running = true;
      }
    });

    if (running) {
      this.intervalCnt = setInterval(() => {
        this.props.getBuilds();
      }, 5000);
    }
  }

  componentWillUnmount() {
    clearInterval(this.intervalCnt);
  }

  reattemptCodeBuild = (buildId) => {
    if (!buildId) {
      return false;
    }
    const { pathResource } = window.FORCE;
    const projectId = pathResource.id;

    exceed
      .fetch({
        api: 'reattemptCodeBuild',
        params: {
          projectId,
          build_result_id: buildId,
        },
        data: {
          build_result_id: buildId,
        },
      })
      .then((res) => {
        if (res && res.success) {
          this.props.getBuilds();
          setTimeout(() => {
            this.componentDidMount();
          }, 5000);
        } else if (res && res.message) {
          Message.error({ title: res.message });
        }
      })
      .catch((err) => {
        console.error(err);
      });
  };

  renderBuildInScanNum = (item) => {
    if (
      item.blocker_count !== undefined ||
      item.critical_count !== undefined ||
      item.major_count !== undefined
    ) {
      return (
        <span className={'num'}>
          Blocker {item.blocker_count} Critical {item.critical_count} Major {item.major_count}
        </span>
      );
    } else {
      return (
        <span>
          <Button
            onClick={() => this.reattemptCodeBuild(item.id)}
            type="primary"
            text
            style={{ marginLeft: 12, verticalAlign: 'bottom' }}
          >
            重试
          </Button>
        </span>
      );
    }
  };

  // 每一项的icon和commits页面相同
  renderBuildTitle = (item) => {
    let tagColor = '';
    let tagTxt = '';
    if (item.state === 'RUNNING') {
      tagColor = 'blue';
      tagTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.Running',
        defaultMessage: '运行中',
      });
    } else if (item.state === 'PASS') {
      tagColor = 'green';
      tagTxt = intl.get({ id: 'code-assets.components.codeScanInfo.Pass', defaultMessage: '通过' });
    } else if (item.state === 'WARNING') {
      tagColor = 'orange';
      tagTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.Alerts',
        defaultMessage: '有告警',
      });
    } else if (item.state === 'FAIL') {
      tagColor = 'red';
      tagTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.Failed',
        defaultMessage: '不通过',
      });
    } else if (item.state === 'ERROR') {
      tagColor = 'red';
      tagTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.RunException',
        defaultMessage: '运行异常',
      });
    } else if (item.state === 'NOT_RUN') {
      tagColor = undefined;
      tagTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.NotRunning',
        defaultMessage: '未运行',
      });
    }
    return (
      <div className={`${prefix}-list-item-left`}>
        <span className="tag-wrapper">
          <Tag color={tagColor} className={'tag'}>
            <span>
              <YunxiaoIcon type="test-grey-fill" />
            </span>
            <span style={{ paddingLeft: 4 }}>{tagTxt}</span>
          </Tag>
        </span>
        <span className={'name'}>{item.task_name}</span>
        {/* 流水线失效 */}
        {getFeature('module_enable.repository.flow') && item.pipeline_invalid ? (
          <Balloon
            closable={false}
            trigger={
              <Tag type="normal" style={{ marginLeft: 8 }}>
                已失效
              </Tag>
            }
          >
            找不到流水线，请前往Flow确认流水线状态{' '}
            <a href={docs('howToUsePipelineDetection')} target="_blank" rel="noreferrer">
              了解更多
            </a>
          </Balloon>
        ) : null}
        {/** 非内置扫描，如流水线，不展示 Blocker Critical Major数量，因为不存在 */}
        {this.isBuildInScan(item) && item.state !== 'RUNNING'
          ? this.renderBuildInScanNum(item)
          : null}
      </div>
    );
  };

  goChangeTab = (curBuildId, buildState) => {
    const { codeReviewDetail, issueDetailList } = this.props;
    const { pathResource } = window.FORCE;
    // 如果是通过则只是打开文件改动页，否则会定位到该类型问题的第一个文件

    // 不是通过的则将面板弹出
    if (buildState !== 'PASS') {
      const filterItem = issueDetailList.find((item) => {
        return item.build_result_id === curBuildId;
      });
      if (filterItem) {
        // 只涉及到最新,为right；
        const side = 'right';
        navigate(
          `/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}/changes#file=${sha1(
            filterItem.file_name,
          )}&line=${filterItem.begin_line}&side=${side}`,
        );
      } else {
        navigate(`/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}/changes`);
      }

      this.props.openCodescanPanel({
        isShowCodeScan: true,
        curBuildId,
      });
    } else {
      navigate(`/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}/changes`);
    }

    this.props.changeMrTabKey('changes');
  };

  // 获取每种状态的数据以及比例
  getStateBuildAndRate = () => {
    // 无论是否卡点，均以全部构建的结果汇总合并卡点整体状态
    // https://teambition.alibaba-inc.com/task/5dd4e914401c761f39599c89
    const { mergeRequestBuilds } = this.props;
    const runningBuilds = mergeRequestBuilds.filter((item) => item.state === 'RUNNING');
    const failBuilds = mergeRequestBuilds.filter((item) => item.state === 'FAIL');
    const passBuilds = mergeRequestBuilds.filter((item) => item.state === 'PASS');
    // 有告警前端展示判断条件： issue_file_count > 0 && blocker_count == 0,且返回为状态为PASS
    const warningBuilds = mergeRequestBuilds.filter((item) => item.state === 'WARNING');
    const errorBuilds = mergeRequestBuilds.filter((item) => item.state === 'ERROR');
    const notRunBuilds = mergeRequestBuilds.filter((item) => item.state === 'NOT_RUN');
    return {
      runningRate: ((runningBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      failRate: ((failBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      passRate: ((passBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      warningRate: ((warningBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      errorRate: ((errorBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      notRunRate: ((notRunBuilds.length / mergeRequestBuilds.length) * 100).toFixed(2),
      runningBuilds,
      failBuilds,
      passBuilds,
      warningBuilds,
      errorBuilds,
      notRunBuilds,
    };
  };

  isBuildInScan = (build) => {
    return ENUM.buildInTaskNames.includes(build.enTaskName);
  };

  renderOverview = () => {
    const { mergeRequestBuilds } = this.props;
    const { isShowCodeScan } = this.state;

    if (!mergeRequestBuilds.length) {
      return null;
    }

    // 没有RUNING态的builds，要关闭定时器
    let running = false;
    mergeRequestBuilds.forEach((item) => {
      if (item.state === 'RUNNING') {
        running = true;
      }
    });

    if (!running && this.intervalCnt !== -1) {
      clearInterval(this.intervalCnt);
    }

    // 判断是否作为卡点
    const noPassRequiredBuilds =
      mergeRequestBuilds.filter((item) => {
        return item.required && item.state !== 'PASS';
      }) || [];

    const {
      // runningRate,
      // failRate,
      // passRate,
      // warningRate,
      // errorRate,
      // notRunRate,
      runningBuilds,
      failBuilds,
      errorBuilds,
      warningBuilds,
      passBuilds,
      notRunBuilds,
    } = this.getStateBuildAndRate();
    let type = '';
    if (runningBuilds.length) {
      type = 'RUNNING';
    } else if (failBuilds.length || errorBuilds.length || notRunBuilds.length) {
      type = 'FAIL';
    } else if (warningBuilds.length) {
      type = 'WARN';
    } else {
      type = 'PASS';
    }

    let curTitleTxt = '';
    let curColor = '';
    let iconType = '';
    if (type === 'RUNNING') {
      curTitleTxt = intl.get(
        {
          id: 'code-assets.components.codeScanInfo.AutomatedCheckCodescanmaptype',
          defaultMessage: '自动化检查{codeScanMapType}',
        },
        { codeScanMapType: codeScanMap[type] },
      );
      curColor = codeScanColorMap[type];
      iconType = codeScanIconMap[type];
    } else if (type === 'NOT_RUN' || (type === 'FAIL' && noPassRequiredBuilds.length !== 0)) {
      curTitleTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.AutomaticCheckFailed',
        defaultMessage: '卡点的自动化检查不通过',
      });
      curColor = '#8c8c8c';
      iconType = 'time-fill';
    } else {
      curTitleTxt = intl.get({
        id: 'code-assets.components.codeScanInfo.TheAutomaticCheckOfCard',
        defaultMessage: '卡点的自动化检查全部通过',
      });
      curColor = '#1dc11d';
      iconType = 'success-fill';
    }
    let itemNumber = 0;
    if (runningBuilds.length) {
      itemNumber += 1;
    }
    if (failBuilds.length) {
      itemNumber += 1;
    }
    if (passBuilds.length) {
      itemNumber += 1;
    }
    if (warningBuilds.length) {
      itemNumber += 1;
    }
    if (errorBuilds.length) {
      itemNumber += 1;
    }
    if (notRunBuilds.length) {
      itemNumber += 1;
    }

    if (itemNumber > 3) {
      return (
        <>
          <div style={{ flex: 1 }}>
            <div className={`${prefix}-title`}>
              {/* 5个状态： 通过、 运行中、 不通过（非卡点）、不通过、未运行 */}
              {/* 扫描状态总览颜色和文案：
                 运行中——蓝色：自动化检查运行中
                 通过、（非卡点）不通过——绿色：卡点的自动化检查通过
                 未运行、（卡点）不通过——红色：卡点的自动化检查不通过 */}
              <YunxiaoIcon type={iconType} style={{ color: curColor }} />
              <span className={`${prefix}-text`}>{curTitleTxt}</span>
            </div>
            <div className={`${prefix}-overview-left`}>
              <div className={`${prefix}-overview-info`}>
                {runningBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="running-dot dot" />
                    <span className="number">
                      {intl.get(
                        {
                          id: 'code-assets.components.codeScanInfo.RunningbuildslengthItemRunning',
                          defaultMessage: '{runningBuildsLength} 项运行中',
                        },
                        { runningBuildsLength: runningBuilds.length },
                      )}
                    </span>
                  </span>
                ) : null}
                {failBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="fail-dot dot" />
                    <span className="number">
                      {failBuilds.length}
                      {intl.get({
                        id: 'code-assets.components.codeScanInfo.ItemFailed',
                        defaultMessage: '项不通过',
                      })}
                      {noPassRequiredBuilds.length === 0
                        ? intl.get({
                            id: 'code-assets.components.codeScanInfo.NonStuckPoint',
                            defaultMessage: '（非卡点）',
                          })
                        : ''}
                    </span>
                  </span>
                ) : null}
                {passBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="pass-dot dot" />
                    <span className="number">
                      {intl.get(
                        {
                          id: 'code-assets.components.codeScanInfo.PassbuildslengthItemPassed',
                          defaultMessage: '{passBuildsLength} 项通过',
                        },
                        { passBuildsLength: passBuilds.length },
                      )}
                    </span>
                  </span>
                ) : null}
                {warningBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="warning-dot dot" />
                    <span className="number">
                      {intl.get(
                        {
                          id: 'code-assets.components.codeScanInfo.WarningbuildslengthHasAnAlert',
                          defaultMessage: '{warningBuildsLength} 项有告警',
                        },
                        { warningBuildsLength: warningBuilds.length },
                      )}
                    </span>
                  </span>
                ) : null}
                {errorBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="error-dot dot" />
                    <span className="number">
                      {intl.get(
                        {
                          id: 'code-assets.components.codeScanInfo.Errorbuildslength',
                          defaultMessage: '{errorBuildsLength} 项运行异常',
                        },
                        { errorBuildsLength: errorBuilds.length },
                      )}
                    </span>
                  </span>
                ) : null}
                {notRunBuilds.length ? (
                  <span className={`${prefix}-overview-info-item`}>
                    <span className="not-run-dot dot" />
                    <span className="number">
                      {intl.get(
                        {
                          id: 'code-assets.components.codeScanInfo.NotrunbuildslengthIsNotRunning',
                          defaultMessage: '{notRunBuildsLength}项未运行',
                        },
                        { notRunBuildsLength: notRunBuilds.length },
                      )}
                    </span>
                  </span>
                ) : null}
              </div>
            </div>
          </div>
          <div className={`${prefix}-overview-arrow`}>
            <YunxiaoIcon
              className="code-scane-arrow"
              type={`arrow-${isShowCodeScan ? 'up' : 'right'}-2-line`}
            />
          </div>
        </>
      );
    }
    return (
      <>
        <div className={`${prefix}-title`}>
          {/* 5个状态： 通过、 运行中、 不通过（非卡点）、不通过、未运行 */}
          {/* 扫描状态总览颜色和文案：
                 运行中——蓝色：自动化检查运行中
                 通过、（非卡点）不通过——绿色：卡点的自动化检查通过
                 未运行、（卡点）不通过——红色：卡点的自动化检查不通过 */}
          <YunxiaoIcon type={iconType} style={{ color: curColor }} />
          <span className={`${prefix}-text`}>{curTitleTxt}</span>
        </div>
        <div className={`${prefix}-overview-left`}>
          <div className={`${prefix}-overview-info`}>
            {runningBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="running-dot dot" />
                <span className="number">
                  {intl.get(
                    {
                      id: 'code-assets.components.codeScanInfo.RunningbuildslengthItemRunning',
                      defaultMessage: '{runningBuildsLength} 项运行中',
                    },
                    { runningBuildsLength: runningBuilds.length },
                  )}
                </span>
              </span>
            ) : null}
            {failBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="fail-dot dot" />
                <span className="number">
                  {failBuilds.length}
                  {intl.get({
                    id: 'code-assets.components.codeScanInfo.ItemFailed',
                    defaultMessage: '项不通过',
                  })}
                  {noPassRequiredBuilds.length === 0
                    ? intl.get({
                        id: 'code-assets.components.codeScanInfo.NonStuckPoint',
                        defaultMessage: '（非卡点）',
                      })
                    : ''}
                </span>
              </span>
            ) : null}
            {passBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="pass-dot dot" />
                <span className="number">
                  {intl.get(
                    {
                      id: 'code-assets.components.codeScanInfo.PassbuildslengthItemPassed',
                      defaultMessage: '{passBuildsLength} 项通过',
                    },
                    { passBuildsLength: passBuilds.length },
                  )}
                </span>
              </span>
            ) : null}
            {warningBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="warning-dot dot" />
                <span className="number">
                  {intl.get(
                    {
                      id: 'code-assets.components.codeScanInfo.WarningbuildslengthHasAnAlert',
                      defaultMessage: '{warningBuildsLength} 项有告警',
                    },
                    { warningBuildsLength: warningBuilds.length },
                  )}
                </span>
              </span>
            ) : null}
            {errorBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="error-dot dot" />
                <span className="number">
                  {intl.get(
                    {
                      id: 'code-assets.components.codeScanInfo.Errorbuildslength',
                      defaultMessage: '{errorBuildsLength} 项运行异常',
                    },
                    { errorBuildsLength: errorBuilds.length },
                  )}
                </span>
              </span>
            ) : null}
            {notRunBuilds.length ? (
              <span className={`${prefix}-overview-info-item`}>
                <span className="not-run-dot dot" />
                <span className="number">
                  {intl.get(
                    {
                      id: 'code-assets.components.codeScanInfo.NotrunbuildslengthIsNotRunning',
                      defaultMessage: '{notRunBuildsLength}项未运行',
                    },
                    { notRunBuildsLength: notRunBuilds.length },
                  )}
                </span>
              </span>
            ) : null}
          </div>
          <div className={`${prefix}-overview-arrow`}>
            <YunxiaoIcon
              className="code-scane-arrow"
              type={`arrow-${isShowCodeScan ? 'up' : 'right'}-2-line`}
            />
          </div>
        </div>
      </>
    );
  };

  render() {
    const { mergeRequestBuilds, codeReviewDetail } = this.props;
    const { isShowCodeScan } = this.state;

    if (!mergeRequestBuilds.length) {
      return null;
    }

    // 没有RUNING态的builds，要关闭定时器
    let running = false;
    mergeRequestBuilds.forEach((item) => {
      if (item.state === 'RUNNING') {
        running = true;
      }
    });

    if (!running && this.intervalCnt !== -1) {
      clearInterval(this.intervalCnt);
    }

    return (
      <div className={`${prefix}`}>
        <div
          className={`${prefix}-overview`}
          onClick={() => {
            track({
              action: isShowCodeScan ? 'hide_automated_inspection' : 'show_automated_inspection',
              page: 'Repo-MR',
              type: '',
              control: '',
              mr_id: codeReviewDetail.id,
            });

            this.setState({
              isShowCodeScan: !isShowCodeScan,
            });
          }}
        >
          {this.renderOverview()}
        </div>
        {/* 具体的小项 */}
        <div style={{ display: isShowCodeScan ? 'block' : 'none' }} className={`${prefix}-list`}>
          {mergeRequestBuilds.map((item) => {
            return (
              <div className={`${prefix}-list-item`}>
                {this.renderBuildTitle(item)}
                <div className={`${prefix}-list-item-right`}>
                  {item.required && (
                    <div
                      className="required"
                      style={{
                        marginRight: this.isBuildInScan(item) && item.state === 'RUNNING' ? 96 : 40,
                      }}
                    >
                      <Tag className="tag">
                        {intl.get({
                          id: 'code-assets.components.codeScanInfo.FreePoint',
                          defaultMessage: '卡点',
                        })}
                      </Tag>
                    </div>
                  )}

                  <div
                    style={{
                      display:
                        this.isBuildInScan(item) && item.state === 'RUNNING' ? 'none' : 'block',
                    }}
                  >
                    {this.isBuildInScan(item) ? (
                      <Button
                        type="primary"
                        text
                        onClick={() => {
                          track({
                            action: 'goto_pipelinelog',
                            page: 'Repo-MR',
                            mr_id: codeReviewDetail.id,
                          });

                          this.goChangeTab(item.id, item.state);
                        }}
                      >
                        {intl.get({
                          id: 'code-assets.components.codeScanInfo.ViewDetails',
                          defaultMessage: '查看详情',
                        })}
                      </Button>
                    ) : (
                      <Button type="primary" text component="a" href={item.url} target="_blank">
                        {intl.get({
                          id: 'code-assets.components.codeScanInfo.ViewDetails',
                          defaultMessage: '查看详情',
                        })}
                      </Button>
                    )}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }
}
